package com.cgc999.host.net;

import android.text.TextUtils;

import androidx.annotation.Nullable;

import com.cgc999.host.config.ApiConfig;
import com.cgc999.host.net.https.SslSocketFactory;
import com.cgc999.host.net.https.UnSafeHostnameVerify;
import com.cgc999.host.net.https.UnSafeTrustManager;
import com.cgc999.host.net.interceptor.HttpCacheInterceptor;
import com.cgc999.host.net.interceptor.HttpHeaderInterceptor;
import com.cgc999.host.net.interceptor.HttpLoggerInterceptor;
import com.cgc999.host.util.AppContextUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.File;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 *
 */
public class RetrofitFactory {
    //单例双重检查
    private static RetrofitFactory Instance;

    private RetrofitFactory() {
        init();
    }

    public static RetrofitFactory getInstance() {
        if (Instance == null) {
            synchronized (RetrofitFactory.class) {
                if (Instance == null) {
                    Instance = new RetrofitFactory();
                }
            }
        }
        return Instance;
    }

    private Retrofit.Builder retrofit;
    private Retrofit build;

    /**
     * OkHttp基础配置
     *
     * @return
     */
    public void init() {
        //指定缓存路径
        File cacheFile = new File(AppContextUtils.getContext().getCacheDir(), "HttpCache");
        //设置缓存大小
        Cache cache = new Cache(cacheFile, 1024 * 1024 * 100);//设置缓存大小为100M

        OkHttpClient.Builder httpClientBuilder = new OkHttpClient().newBuilder()
                .readTimeout(ApiConfig.getDefaultTimeout(), TimeUnit.MILLISECONDS) //设置默认读取超时时间
                .writeTimeout(ApiConfig.getDefaultTimeout(), TimeUnit.SECONDS)//写超时超时
                .connectTimeout(ApiConfig.getDefaultTimeout(), TimeUnit.MILLISECONDS)//设置默认连接超时时间
                .addInterceptor(HttpLoggerInterceptor.getLoggerInterceptor()) //设置日志拦截器
                .addInterceptor(new HttpHeaderInterceptor()) //设置请求头拦截器
                .addNetworkInterceptor(new HttpCacheInterceptor())//设置缓存拦截器
//                .addInterceptor(tokenInterceptor) token请求相关设置
//                .cookieJar(cookieJar)//cookie的本地保存管理
                .retryOnConnectionFailure(true)     //是否失败重新请求连接
                .cache(cache);//设置缓存大小

        /**
         * https 请求相关配置
         */
        if (ApiConfig.getOpenHttps()) {
            httpClientBuilder.sslSocketFactory(1 == ApiConfig.getSslSocketConfigure().getVerifyType() ?
                    SslSocketFactory.getSSLSocketFactory(ApiConfig.getSslSocketConfigure().getCertificateInputStream()) :
                    SslSocketFactory.getSSLSocketFactory(), new UnSafeTrustManager());
            httpClientBuilder.hostnameVerifier(new UnSafeHostnameVerify());
        }

        OkHttpClient httpClient = httpClientBuilder.build();

        //json数据解析
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .serializeNulls()
                .registerTypeAdapterFactory(new NullTypeAdapterFactory())
                .setPrettyPrinting()
                .disableHtmlEscaping()
                .create();

        retrofit = new Retrofit.Builder()
                .client(httpClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create());

        if (!TextUtils.isEmpty(ApiConfig.getBaseUrl())) {
            build = retrofit.baseUrl(ApiConfig.getBaseUrl()).build();
        }
    }

    /**
     * 根据Api接口类生成Api实体
     *
     * @param clazz 传入的Api接口类
     * @return Api实体类
     */
    public <T> T create(Class<T> clazz) {
        checkNotNull(build, "BaseUrl not init,you should init first!");
        return build.create(clazz);
    }

    /**
     * 根据Api接口类生成Api实体
     *
     * @param baseUrl baseUrl
     * @param clazz   传入的Api接口类
     * @return Api实体类
     */
    public <T> T create(String baseUrl, Class<T> clazz) {
        return retrofit.baseUrl(baseUrl).build().create(clazz);
    }

    private <T> T checkNotNull(@Nullable T object, String message) {
        if (object == null) {
            throw new NullPointerException(message);
        }
        return object;
    }
}
